#include <AknIconUtils.h>
#include <AknIconArray.h>
#include <AknLists.h>
#include <APGCLI.H>

#include <BADESCA.H>
#include <GULICON.H>
#include <EIKCLBD.H>
#include <barsread.h>
#include <aknnavi.h>
#include <akntabgrp.h>
#include <aknnavide.h>
#include <aknsfld.h>

#include <MrLockUi.rsg>

#include "ChooseApplicationDialog.h"
#include "Utils.h"


static void AppendAppCaptionL(TDes& aName, TApaAppInfo& aAppInfo)
{
	TPtrC caption;
	if (aAppInfo.iCaption.Length() > 1)
		caption.Set(aAppInfo.iCaption);
	else if (aAppInfo.iShortCaption.Length() > 1)
		caption.Set(aAppInfo.iShortCaption);
	else if (aAppInfo.iFullName.Length() > 0)
	{
		TInt ind = aAppInfo.iFullName.LocateReverse('\\');
		caption.Set(aAppInfo.iFullName.Right(aAppInfo.iFullName.Length() - ind - 1));
	}
	aName.Append(caption.Left(30));
}

static TUid RemoveUidL(TDes& aItemName)
{
	TInt pos = aItemName.LocateReverse(TChar('\t'));
	TBuf<30> uidBuf = aItemName.Mid(pos+3);
	TLex16 lex(uidBuf);
	TUint32 uidInt;
	lex.Val(uidInt, EHex);
	aItemName.Copy(aItemName.Left(pos));
	return TUid::Uid(uidInt);
}

CChooseApplicationDialog::CChooseApplicationDialog( TInt &aIndex, CDesCArray *aArray, RArray< TUid >& aMenuItems )
: CMySelectionListDialog( aIndex, aMenuItems, aArray, NULL )
{
}

CChooseApplicationDialog::~CChooseApplicationDialog()
{
	HideTabsL();
}

void CChooseApplicationDialog::PreLayoutDynInitL()
{
	CMySelectionListDialog::PreLayoutDynInitL();
	
	ShowTabsL();
	
	iListBox = static_cast< CAknColumnListBox* >( ListBox() );
	iListBoxItems = static_cast< CDesCArray* >( iListBox->Model()->ItemTextArray() );
	for( TInt i = 0; i < iMenuItems.Count(); i++ )
	{
		iSelectedItems.Append( iMenuItems[ i ] );
	}

	LoadIconsL();
	LoadItemsL();
}

void CChooseApplicationDialog::LoadItemsL()
{
	TBuf< 100 > itemName;
	RApaLsSession lsSession;
	lsSession.Connect();
	CleanupClosePushL( lsSession );//+lsSession
	lsSession.GetAllApps();
	TInt appCount = 0;
	lsSession.AppCount( appCount );
	TApaAppInfo appInfo;
	TApaAppCapabilityBuf capability;
	CDesCArrayFlat* arr = new (ELeave) CDesCArrayFlat( appCount + 1 );
	CleanupStack::PushL( arr );//+arr

	CDesCArrayFlat* arr2 = new (ELeave) CDesCArrayFlat( iSelectedItems.Count() + 1 );
	CleanupStack::PushL( arr2 );//+arr2
	TTime now;
	now.HomeTime();

	while (lsSession.GetNextApp( appInfo ) == KErrNone)
	{
		lsSession.GetAppCapability( capability,appInfo.iUid );
		if( iHiddenAppsOnly != capability().iAppIsHidden )
			continue;

		itemName.Zero();
		AppendAppCaptionL( itemName, appInfo );
		itemName.AppendFormat( _L("\t0x%08x"), appInfo.iUid.iUid );
		TBool marked = ( KErrNotFound != iSelectedItems.Find( appInfo.iUid ) );

		if (EFalse == marked)
		{
			arr->AppendL(itemName);
		}
		else
		{
			arr2->AppendL(itemName);
		}
	}

	iListBoxItems->Reset();
	iItemsUids.Reset();

	for (TInt i = 0;i < arr2->Count();i++)
	{
		itemName.Copy(arr2->operator[](i));
		TUid appUid = RemoveUidL(itemName);
		TBuf< 100 > newItem;
		newItem.Format( _L("1\t%S"), &itemName );
		iListBoxItems->AppendL( newItem );
		iItemsUids.Append( appUid );
	}

	arr->Sort();

	for (TInt i = 0;i < arr->Count();i++)
	{
		itemName.Copy(arr->operator[](i));
		TUid appUid = RemoveUidL(itemName);
		TBuf< 100 > newItem;
		newItem.Format( _L("0\t%S"), &itemName );
		iListBoxItems->AppendL( newItem );
		iItemsUids.Append( appUid );
	}

	CleanupStack::PopAndDestroy();//-arr2
	CleanupStack::PopAndDestroy();//-arr
	CleanupStack::PopAndDestroy();//-lsSession
	ListBox()->HandleItemAdditionL();
}

TBool CChooseApplicationDialog::ShowDialogL( RArray< TUid >& aMenuItems )
{
	TInt openedItem = 0;
	CDesCArrayFlat* arrayOfItems = new( ELeave ) CDesCArrayFlat( 2 );
	CleanupStack::PushL( arrayOfItems );
	CChooseApplicationDialog* dialog = new( ELeave ) CChooseApplicationDialog( openedItem, arrayOfItems, aMenuItems );
	TBool res = dialog->ExecuteLD( R_MY_SELECTION_DIALOG );

	CleanupStack::PopAndDestroy( arrayOfItems );
	
	return res;
}

void CChooseApplicationDialog::ShowTabsL()
{
	HideTabsL();
	TResourceReader reader;
	iCoeEnv->CreateResourceReaderLC( reader, R_APPLICATION_DIALOG_NAVI_DECORATOR );//+reader
	CAknNavigationControlContainer* np = ( CAknNavigationControlContainer* )  CEikonEnv::Static()->AppUiFactory()->StatusPane()->ControlL(TUid::Uid(EEikStatusPaneUidNavi));
	iNaviTabs = np->CreateTabGroupL( reader, this );
	CleanupStack::PopAndDestroy();//-reader
	//iNaviTabs->SetNaviDecoratorObserver( this );
	
	CAknTabGroup* tabGroup = static_cast< CAknTabGroup* >( iNaviTabs->DecoratedControl() );
	tabGroup->SetActiveTabByIndex( 0 );
	
	np->PushL( *iNaviTabs );
}

void CChooseApplicationDialog::HideTabsL()
{
	if( iNaviTabs )
	{
		CAknNavigationControlContainer* np = (CAknNavigationControlContainer*)  CEikonEnv::Static()->AppUiFactory()->StatusPane()->ControlL(TUid::Uid(EEikStatusPaneUidNavi));
		np->Pop();

		delete iNaviTabs;
		iNaviTabs = NULL;
	}
}

void CChooseApplicationDialog::TabChangedL( TInt aIndex )
{
	iHiddenAppsOnly = ( aIndex == 1 );
	LoadItemsL();
}

#ifndef __S60_50__
TKeyResponse CChooseApplicationDialog::OfferKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType)
{
	TInt code = aKeyEvent.iCode;
	CAknTabGroup* tabGroup = NULL;

	if (code == EKeyLeftArrow || code == EKeyRightArrow)
	{
		CAknNavigationControlContainer* np = (CAknNavigationControlContainer*) CEikonEnv::Static()->AppUiFactory()->StatusPane()->ControlL(TUid::Uid(EEikStatusPaneUidNavi));
		tabGroup = static_cast<CAknTabGroup*>(np->Top()->DecoratedControl());
	}

    switch (code)
    {
        case EKeyLeftArrow:
        {//go to the Keypad view
        	TInt newIndex = tabGroup->ActiveTabIndex()-1;
            if (newIndex >= 0)
			{
				tabGroup->SetActiveTabByIndex(newIndex);
				TabChangedL( newIndex );
				return EKeyWasConsumed;
            }
			break;
		}
        case EKeyRightArrow:
        {//go to LockPhoneView
			TInt newIndex = tabGroup->ActiveTabIndex()+1;
			if (newIndex < tabGroup->TabCount())
			{
				tabGroup->SetActiveTabByIndex(newIndex);
				TabChangedL( newIndex );
				return EKeyWasConsumed;
			}
			break; 
        }
        case EKeyOK:
        	TryExitL( EAknSoftkeySelect );
        	return EKeyWasConsumed;
        default:
        	return CAknSelectionListDialog::OfferKeyEventL(aKeyEvent, aType);
        	break;
	}

	return EKeyWasConsumed;
}
#endif
